# -*- coding: utf8 -*-
########################################################################
# Copyright (c) 2008 Burdakov Daniel <kreved@kreved.org>               #
#                                                                      #
# This file is part of PyWoW.                                          #
#                                                                      #
# PyWoW is free software: you can redistribute it and/or modify        #
# it under the terms of the GNU General Public License as published by #
# the Free Software Foundation, either version 3 of the License, or    #
# (at your option) any later version.                                  #
#                                                                      #
# PyWoW is distributed in the hope that it will be useful,             #
# but WITHOUT ANY WARRANTY; without even the implied warranty of       #
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        #
# GNU General Public License for more details.                         #
#                                                                      #
# You should have received a copy of the GNU General Public License    #
# along with PyWoW.     If not, see <http://www.gnu.org/licenses/>.    #
########################################################################

from twisted.internet import protocol
from constants import *

class RealmPacketProtocol(protocol.Protocol):
 
 """этот протокол при получении данных в зависимости от первого байта
 и своего состояния (напоминает машину тьюринга :D) выбирает чем
 распаковать данные, и какому обработчику передать готовый пакет
 
 в self.packet_handlers хранится список обработчиков и пакетов..
 это список, каждый элемент которого содержит (cmd, template, handler, statuses)
  cmd - первый байт
  template - пакет (из модуля packets.py)
  handler - функция, которая получит готовый пакет
  statuses - список статусов, при которых этот элемент можно использовать.
 """
 
 debug = False
 
 def connectionMade(self):
  self.status = NOTHING
  self.buf = ''
  self.packet_handlers = []
 def dataReceived(self, data):
  if self.debug: print "received %s bytes: %s" % (len(data), repr(data))
  self.buf += data
  bytes = 1
  while (bytes>0) and self.buf:
   # пока есть что читать из буфера
   cmd = ord(self.buf[0])
   p = [h for h in self.packet_handlers if (h[0] == cmd) and (self.status in h[3])]
   if p:
    cmd, template, handler, valid_statuses = p[0]
    packet = template()
    bytes = packet.unpack(self.buf)
    if bytes > 0:
     # если пакет прочитан, то отправляем его на обработку, и удаляем из буфера прочитанное
     if self.debug: print "Unpacked <%s>" % packet.__class__
     handler(packet)
     self.buf = self.buf[bytes:]
   else:
    print "Received unknown packet. Dropping connection."
    bytes = 0
    self.transport.loseConnection()
 def send(self, packet):
  self.transport.write(packet.pack())
